#####
##  HP OneView Sample REST in PERL
##
##  Written by:  William Fitzpatrick
##		 		 Experis Technology Group
##		 		 bfitzpatrick@experistg.com
##
##  This sample logs into OneView using a backup admin account, submits a 
##  backup job, waits for the job to complete by polling the jobs status, 
##  Once the job is complete the script downloads the resulting file in 
##  the local directory, then logs off...
##
##  Currently I use this script to automate OneView backups.
##
##  This script was tested against OneView 1.20.01 using Strawberry 
##  PERL 5.20.2.1 (64bit) available from 
##  http://strawberryperl.com/download/5.20.2.1/strawberry-perl-5.20.2.1-64bit.msi
##
##  Extra modules required REST::Client and JSON, both are available by
##  typing the following 'CPAN install REST::Client JSON' on the command 
##  prompt after PERL is installed.
##
#####
##  No warranty expressed or implied!
##
##  This script program is distributed in the hope that it will be useful, 
##  but without any warranty. It is provided "as is" without warranty of 
##  any kind, either expressed or implied, including, but not limited to,
##  the implied warranties of merchantability and fitness for a particular 
##  purpose. The entire risk as to the quality and performance of the 
##  program is with you. Should the program prove defective, you
##  assume the cost of all necessary servicing, repair or correction.
##
##  In no event will I be liable to you for damages, including any general, 
##  special, incidental or consequential damages arising out of the use or 
##  inability to use the program (including but not limited to loss of data 
##  or data being rendered inaccurate or losses sustained by you or third 
##  parties or a failure of the program to operate with any other programs), 
##  even if the I have been advised of the possibility of such damages.
##
#####
##  HP OneView API Reference
##  http://h17007.www1.hp.com/docs/enterprise/servers/oneviewhelp/oneviewRESTAPI/content/images/api/index.html
#####
use strict;
use warnings;
use utf8;

use REST::Client;
use JSON;
use File::Basename;

my $host   = 'https://hponeview.hq.experistg.com';
my $client = REST::Client->new();
$client->setHost($host);
$client->addHeader( 'Content_Type', 'application/json' );

my %data = (
    'authLoginDomain' => 'Domain',
    'password'        => 'Pass',
    'userName'        => 'User',
);

#translate the data hash into json notation
my $data = encode_json( \%data );

print "Logging in...\n";
$client->POST( '/rest/login-sessions', $data );
my $json      = $client->responseContent();
my $sessionID = "";
my $returned  = decode_json($json);           #decode the response
$sessionID = $returned->{'sessionID'};
if ( $client->responseCode() != 200 ) {
    print "Cant login to OneView...\n";
    exit;
}
my $headers = { Auth => $sessionID };
$client->addHeader( 'Auth', $sessionID );     # add auth/sessionID to headers
print "Logged in...\n";

#start a Backup
print "Submit backup job...\n";
$client->POST('/rest/backups');
$json     = $client->responseContent();
$returned = decode_json($json);
my $associatedResourceUri = $returned->{'associatedResourceUri'};

my $errorCode       = "";
my $status          = '';
my $percentComplete = 0;
my $errorMessage    = '';
my $downloadUri     = '';

do {
    $status          = '';
    $percentComplete = 0;
    $errorMessage    = '';
    $errorCode       = "";

    print "waiting for job completion...\n";
    sleep 20;

    $client->GET($associatedResourceUri);

    #print $client->responseCode() . "\n"; should be 200;
    $json            = $client->responseContent();
    $returned        = decode_json($json);
    $status          = $returned->{'status'};
    $percentComplete = $returned->{'percentComplete'};
    $errorMessage    = $returned->{'errorMessage'};
    $downloadUri     = $returned->{'downloadUri'};

    print "percentComplete = '" . $percentComplete . "'\n";

    #print "    downloadUri = '" . $downloadUri . "'\n";
    #print "         status = '" . $status . "'\n";

} while ( $status ne 'SUCCEEDED' || $errorMessage ne '' );

my $filename;
if ( $status eq 'SUCCEEDED' ) {

    $client->addHeader( 'Accept',
        'application/octetstream;q=0.8,application/json' );
    $client->GET($downloadUri);
    $json = $client->responseContent();
    my $onetimefile =
      substr( $client->responseHeader('Location'), length($host) );

    $filename = basename($onetimefile);
    print "Saving '" . $filename . "' to local directory...\n";
    $client->GET($onetimefile);

    open( my $out, '>:raw', $filename ) or die "Unable to open: $!";
    print $out $client->responseContent();
    close($out);

}

print "Loggin off OneView...\n";
$client->DELETE('/rest/login-sessions');
print "Loged off OneView successfully...\n" if $client->responseCode() == 204;

exit;
